// (c) Copyright 2013-2014 Stephen Gold <sgold@sonic.net>
// Distributed under the terms of the GNU General Public License

/*
 This file is part of the Bats Game.

 The Bats Game is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by the
 Free Software Foundation, either version 3 of the License, or (at your
 option) any later version.

 The Bats Game is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.

 You should have received a copy of the GNU General Public License
 along with the Bats Game.  If not, see <http://www.gnu.org/licenses/>.
 */
package bats.control;

import bats.SpatialProperties;
import bats.scene.PickablesNode;
import bats.scene.WorldNode;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import java.util.logging.Level;
import java.util.logging.Logger;
import jme3utilities.MyString;
import jme3utilities.SimpleControl;

/**
 * A simple control to manage the visibility of a child spatial.
 * <p>
 * Each instance is disabled at creation.
 *
 * @author Stephen Gold <sgold@sonic.net>
 */
public class RevealControl
        extends SimpleControl {
    // *************************************************************************
    // constants

    /**
     * message logger for this class
     */
    final private static Logger logger =
            Logger.getLogger(RevealControl.class.getName());
    // *************************************************************************
    // fields
    /**
     * which spatial to manage: set by constructor
     */
    final private Spatial child;
    // *************************************************************************
    // constructors

    /**
     * Instantiate a disabled control for a specified child.
     *
     * @param child (not null)
     */
    public RevealControl(Spatial child) {
        assert child != null;
        this.child = child;

        super.setEnabled(false);
    }
    // *************************************************************************
    // AbstractControl methods

    /**
     * Enable or disable this control.
     *
     * @param newState if true, enable the control; if false, disable it
     */
    @Override
    public void setEnabled(boolean newState) {
        Node parent = (Node) spatial;
        if (isEnabled() && newState == false) {
            logger.log(Level.INFO, "detach {0} from {1}",
                    new Object[]{
                MyString.quote(child.getName()),
                MyString.quote(spatial.getName())
            });
            int position = parent.detachChild(child);
            assert position >= 0 : position;

        } else if (!isEnabled() && newState == true) {
            logger.log(Level.INFO, "attach {0} to {1}",
                    new Object[]{
                MyString.quote(child.getName()),
                MyString.quote(spatial.getName())
            });
            parent.attachChild(child);
            /*
             * Spatials don't get added to the pickable list until they're
             * revealed, and then only if they have a pickType set.  This
             * prevents hidden units from being picked or attacked.
             */
            if (SpatialProperties.hasPickType(spatial)) {
                PickablesNode pickables =
                        WorldNode.find(spatial).getPickables();
                pickables.add(spatial);
            }
        }

        super.setEnabled(newState);
    }
}